#include <iostream>
#include <ctime>

#define DBG_LEVEL 0
#define INF_LEVEL 1
#define ERR_LEVEL 2
#define DEFAULT_LEVEL DBG_LEVEL

#define RESET_COLOR "\033[0m"
#define DEBUG_COLOR "\033[34m" // Blue
#define INFO_COLOR "\033[32m"  // Green
#define ERROR_COLOR "\033[31m" // Red

#define LOG(lev_col, lev_str, level, format, ...) {               \
    if(level >= DBG_LEVEL)                      \
    {                                           \
        time_t nowtime = time(nullptr);         \
        struct tm* ptm = localtime(&nowtime);   \
        short strlen_max = 32;                  \
        char time_str[strlen_max];              \
        strftime(time_str, strlen_max - 1, "%H:%M:%S", ptm);    \
        printf("%s[%s]%s[%s][%s:%d] " format "\n",                 \
            lev_col, lev_str, RESET_COLOR, time_str, __FILE__, __LINE__, ##__VA_ARGS__);  \
    }                                           \
}

#define DLOG(format, ...) { LOG(DEBUG_COLOR, "DEBUG", DBG_LEVEL, format, ##__VA_ARGS__); }
#define ILOG(format, ...) { LOG(INFO_COLOR, "INFO", INF_LEVEL, format, ##__VA_ARGS__); }
#define ELOG(format, ...) { LOG(ERROR_COLOR, "ERROR", ERR_LEVEL, format, ##__VA_ARGS__); }
